﻿using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FreeDream.Common.CacheTwoHelper
{
    /// <summary>
    /// 缓存接口实现
    /// </summary>
    public class MemoryCacheService : ICacheService
    {
        //services.AddMemoryCache(options => {
        //    // 缓存最大为100份
        //    //##注意netcore中的缓存是没有单位的，缓存项和缓存的相对关系
        //    options.SizeLimit = 2;
        //    //缓存满了时候压缩20%的优先级较低的数据
        //    options.CompactionPercentage = 0.2;
        //    //两秒钟查找一次过期项
        //    options.ExpirationScanFrequency = TimeSpan.FromSeconds(2);
        //});

        protected IMemoryCache _cache;

        public MemoryCacheService(IMemoryCache cache)
        {
            _cache = cache;
        }

        public bool Add(string key, object value, int ExpirtionTime = 20)
        {
            if (!string.IsNullOrEmpty(key))
            {
                //MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions()
                //{
                //    //滑动过期时间 20秒没有访问则清除
                //    SlidingExpiration = TimeSpan.FromSeconds(ExpirtionTime),
                //    //设置份数
                //    Size = 1,
                //    //优先级
                //    Priority = CacheItemPriority.Low,
                //    //AbsoluteExpiration =  DateTimeOffset.Now.AddSeconds(ExpirtionTime),
                //};
                ////过期回掉
                //cacheEntityOps.RegisterPostEvictionCallback((keyInfo, valueInfo, reason, state) =>
                //{
                //    Console.WriteLine($"回调函数输出【键:{keyInfo},值:{valueInfo},被清除的原因:{reason}】");
                //});
                //_cache.Set(key, value, cacheEntityOps);

                _cache.Set(key, value, DateTimeOffset.Now.AddSeconds(ExpirtionTime));
            }
            return true;
        }

        public bool Remove(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                return false;
            }
            if (Exists(key))
            {
                _cache.Remove(key);
                return true;
            }
            return false;
        }


        public bool Exists(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                return false;
            }

            object cache;
            return _cache.TryGetValue(key, out cache);
        }

        public string GetValue(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                return null;
            }
            if (Exists(key))
            {
                return _cache.Get(key).ToString();
            }
            return null;
        }



        public void SetValue<T>(string key, T value, int absoluteTimeoutSeconds)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key");
            }
            T t;
            if (_cache.TryGetValue<T>(key, out t))
            {
                _cache.Remove(key);
            }
            _cache.Set<T>(key, value, DateTimeOffset.Now.AddSeconds(absoluteTimeoutSeconds));
        }

        public void SetValue<T>(string key, T value, int absoluteTimeoutSeconds, int slidingExpirationSeconds)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key");
            }
            T t;
            if (_cache.TryGetValue<T>(key, out t))
            {
                _cache.Remove(key);
            }
            _cache.Set(key, value, new MemoryCacheEntryOptions()

            {
                AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(absoluteTimeoutSeconds),  //绝对超时时间，
                SlidingExpiration = TimeSpan.FromSeconds(slidingExpirationSeconds),  //不访问超时时间（在这个指定的时段内没有使用则过期，否则顺延）
            });
        }
    }
}
